package org.rsbot.util;

import java.awt.Image;
import java.awt.Toolkit;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.LogManager;

import javax.swing.filechooser.FileSystemView;

import org.rsbot.log.LogFormatter;
import org.rsbot.log.SystemConsoleHandler;
import org.rsbot.log.TextAreaLogHandler;

public class GlobalConfiguration {

    public enum OperatingSystem {

        MAC, WINDOWS, LINUX, UNKNOWN
    }

    public static class Paths {

        public static class Resources {

            public static final String ROOT = "resources";
            public static final String SCRIPTS = Paths.SCRIPTS_NAME_SRC + "/";
            public static final String ROOT_IMG = "/" + Resources.ROOT + "/images";
            public static final String ICON = Resources.ROOT_IMG + "/icon.png";
            public static final String ICON_DELETE = Resources.ROOT_IMG + "/delete.png";
            public static final String ICON_PLAY = Resources.ROOT_IMG + "/control_play_blue.png";
            public static final String ICON_PAUSE = Resources.ROOT_IMG + "/control_pause.png";
            public static final String ICON_ADD = Resources.ROOT_IMG + "/add.png";
            public static final String ICON_ADD_OVER = Resources.ROOT_IMG + "/add_over.png";
            public static final String ICON_ADD_DOWN = Resources.ROOT_IMG + "/add_down.png";
            public static final String ICON_HOME = Resources.ROOT_IMG + "/home.png";
            public static final String ICON_BOT = Resources.ROOT_IMG + "/bot.png";
            public static final String ICON_CLOSE = Resources.ROOT_IMG + "/close.png";
            public static final String ICON_CLOSE_OVER = Resources.ROOT_IMG + "/close_over.png";
            public static final String ICON_TICK = Resources.ROOT_IMG + "/tick.png";
            public static final String ICON_MOUSE = Resources.ROOT_IMG + "/mouse.png";
            public static final String ICON_KEYBOARD = Resources.ROOT_IMG + "/keyboard.png";
            public static final String ICON_CONNECT = Resources.ROOT_IMG + "/connect.png";
            public static final String ICON_DISCONNECT = Resources.ROOT_IMG + "/disconnect.png";
            public static final String ICON_START = Resources.ROOT_IMG + "/control_play.png";
            public static final String ICON_SCRIPT_BDL = Resources.ROOT_IMG + "/script_bdl.png";
            public static final String ICON_SCRIPT_DRM = Resources.ROOT_IMG + "/script_drm.png";
            public static final String ICON_SCRIPT_PRE = Resources.ROOT_IMG + "/script_pre.png";
            public static final String ICON_SCRIPT_SRC = Resources.ROOT_IMG + "/script_src.png";
            public static final String UPARROW = Resources.ROOT_IMG + "/arrow_up.png";
            public static final String DOWNARROW = Resources.ROOT_IMG + "/arrow_down.png";
            public static final String CPU = Resources.ROOT_IMG + "/cpu.png";
            public static final String BUG = Resources.ROOT_IMG + "/bug.png";
            public static final String ACCOUNT = Resources.ROOT_IMG + "/account.png";
            public static final String ABOUT = Resources.ROOT_IMG + "/about.png";
            public static final String HOME_ICON = Resources.ROOT_IMG + "/home-icon.png";
            public static final String LOG = Resources.ROOT_IMG + "/log.png";
            public static final String CONSOLE = Resources.ROOT_IMG + "/console.png";
            public static final String SPLASH = Resources.ROOT_IMG + "/splash.png";
            public static final String SCRIPT_EDIT = Resources.ROOT_IMG + "/script_edit.png";
            public static final String PENCIL = Resources.ROOT_IMG + "/pencil.png";
            public static final String GUI_BUTTON = Resources.ROOT_IMG + "/gui_button.png";
            public static final String GUI_CLOSE = Resources.ROOT_IMG + "/gui_close.png";
            public static final String HELP = Resources.ROOT_IMG + "/help.png";
            public static final String SHOT_DO = Resources.ROOT_IMG + "/shot_do.png";
            public static final String SHOT_UN_DO = Resources.ROOT_IMG + "/shotun_do.png";
            public static final String STOP_DO = Resources.ROOT_IMG + "/stop.png";
            public static final String TOOLS_HIDE = Resources.ROOT_IMG + "/tools_gui.png";
            public static final String BOTTOM_HIDE = Resources.ROOT_IMG + "/bottom_gui.png";
            public static final String TRAY_HIDE = Resources.ROOT_IMG + "/tray_icon.png";
            public static final String WEB_SMALL = Resources.ROOT_IMG + "/web_small.png";
            public static final String WIKI = Resources.ROOT_IMG + "/wiki.png";
            public static final String FACE = Resources.ROOT_IMG + "/face.png";
            public static final String TWIT = Resources.ROOT_IMG + "/twit.png";
            public static final String CUT = Resources.ROOT_IMG + "/cut.png";
            public static final String COPY = Resources.ROOT_IMG + "/copy.png";
            public static final String PASTE = Resources.ROOT_IMG + "/paste.png";
            public static final String SAVE = Resources.ROOT_IMG + "/save.png";
            public static final String ENF = Resources.ROOT_IMG + "/enfinity.png";
            public static final String IRC = Resources.ROOT_IMG + "/irc.png";
            public static final String REWARD = Resources.ROOT_IMG + "/reward.png";
            public static final String DELAY = Resources.ROOT_IMG + "/delay.png";
            public static final String OPTION = Resources.ROOT_IMG + "/option.png";
            public static final String DEV = Resources.ROOT_IMG + "/dev.png";
            public static final String VERSION = Resources.ROOT + "/version.dat";
            public static final String ITEMID = Resources.ROOT + "/ItemID.dat";
            public static final String NPCID = Resources.ROOT + "/NPCID.dat";
        }

        public static class URLs {

            public static final String ITEMID = "http://wyeupijgdijpzgfi.googlecode.com/svn/trunk/ItemID.dat";
            public static final String SVNDAT = "http://wyeupijgdijpzgfi.googlecode.com/svn/trunk/";
            public static final String UPDATER = "http://infinity-client.googlecode.com/svn/trunk/";
            public static final String DOWNLOAD = SVNDAT + "Uglyness";
            public static final String UPDATE = SVNDAT + "mod";
            public static final String VERSION = SVNDAT + "version.dat";
            public static final String PROJECT = "http://code.google.com/p/infinity-client/";
            public static final String SITE = "http://www.runedev-infinity.org/";
        }
        public static final String ROOT = "." + File.separator + "resources";
        public static final String COMPILE_SCRIPTS_BAT = "Compile-Scripts.bat";
        public static final String COMPILE_SCRIPTS_SH = "compile-scripts.sh";
        public static final String COMPILE_FIND_JDK = "FindJDK.bat";
        public static final String ROOT_IMG = Paths.ROOT + File.separator + "images";
        public static final String ICON = Paths.ROOT_IMG + File.separator + "icon.png";
        public static final String ICON_DELETE = Paths.ROOT_IMG + File.separator + "delete.png";
        public static final String ICON_PLAY = Paths.ROOT_IMG + File.separator + "control_play_blue.png";
        public static final String ICON_PAUSE = Paths.ROOT_IMG + File.separator + "control_pause.png";
        public static final String ICON_ADD = Paths.ROOT_IMG + File.separator + "add.png";
        public static final String ICON_ADD_OVER = Paths.ROOT_IMG + File.separator + "add_over.png";
        public static final String ICON_ADD_DOWN = Paths.ROOT_IMG + File.separator + "add_down.png";
        public static final String ICON_HOME = Paths.ROOT_IMG + File.separator + "home.png";
        public static final String ICON_BOT = Paths.ROOT_IMG + File.separator + "bot.png";
        public static final String ICON_CLOSE = Paths.ROOT_IMG + File.separator + "close.png";
        public static final String ICON_CLOSE_OVER = Paths.ROOT_IMG + File.separator + "close_over.png";
        public static final String ICON_TICK = Paths.ROOT_IMG + File.separator + "tick.png";
        public static final String ICON_MOUSE = Paths.ROOT_IMG + File.separator + "mouse.png";
        public static final String ICON_KEYBOARD = Paths.ROOT_IMG + File.separator + "keyboard.png";
        public static final String ICON_CONNECT = Paths.ROOT_IMG + File.separator + "connect.png";
        public static final String ICON_DISCONNECT = Paths.ROOT_IMG + File.separator + "disconnect.png";
        public static final String ICON_START = Paths.ROOT_IMG + File.separator + "control_play.png";
        public static final String ICON_SCRIPT_BDL = Paths.ROOT_IMG + File.separator + "script_bdl.png";
        public static final String ICON_SCRIPT_DRM = Paths.ROOT_IMG + File.separator + "script_drm.png";
        public static final String ICON_SCRIPT_PRE = Paths.ROOT_IMG + File.separator + "script_pre.png";
        public static final String ICON_SCRIPT_SRC = Paths.ROOT_IMG + File.separator + "script_src.png";
        public static final String UPARROW = Paths.ROOT_IMG + File.separator + "arrow_up.png";
        public static final String DOWNARROW = Paths.ROOT_IMG + File.separator + "arrow_down.png";
        public static final String BUG = Paths.ROOT_IMG + File.separator + "bug.png";
        public static final String ACCOUNT = Paths.ROOT_IMG + File.separator + "account.png";
        public static final String ABOUT = Paths.ROOT_IMG + File.separator + "about.png";
        public static final String CPU = Paths.ROOT_IMG + File.separator + "cpu.png";
        public static final String HOME_ICON = Paths.ROOT_IMG + File.separator + "home-icon.png";
        public static final String LOG = Paths.ROOT_IMG + File.separator + "log.png";
        public static final String CONSOLE = Paths.ROOT_IMG + File.separator + "console.png";
        public static final String SPLASH = Paths.ROOT_IMG + File.separator + "splash.png";
        public static final String SCRIPT_EDIT = Paths.ROOT_IMG + "/script_edit.png";
        public static final String PENCIL = Paths.ROOT_IMG + "/pencil.png";
        public static final String GUI = Paths.ROOT_IMG + "/gui.png";
        public static final String GUI_BUTTON = Paths.ROOT_IMG + "/gui_button.png";
        public static final String GUI_CLOSE = Paths.ROOT_IMG + "/gui_close.png";
        public static final String HELP = Paths.ROOT_IMG + "/help.png";
        public static final String ICON_STOP = Paths.ROOT_IMG + File.separator + "stop.png";
        public static final String SHOT_DO = Paths.ROOT_IMG + File.separator + "shot_do.png";
        public static final String SHOT_UN_DO = Paths.ROOT_IMG + File.separator + "shotun_do.png";
        public static final String STOP_DO = Paths.ROOT_IMG + File.separator + "stop.png";
        public static final String TOOLS_HIDE = Paths.ROOT_IMG + File.separator + "tools_gui.png";
        public static final String BOTTOM_HIDE = Paths.ROOT_IMG + File.separator + "bottom_gui.png";
        public static final String TRAY_HIDE = Paths.ROOT_IMG + File.separator + "tray_icon.png";
        public static final String WEB_SMALL = Paths.ROOT_IMG + File.separator + "web_small.png";
        public static final String WIKI = Paths.ROOT_IMG + File.separator + "wiki.png";
        public static final String FACE = Paths.ROOT_IMG + File.separator + "face.png";
        public static final String TWIT = Paths.ROOT_IMG + File.separator + "twit.png";
        public static final String CUT = Paths.ROOT_IMG + File.separator + "cut.png";
        public static final String COPY = Paths.ROOT_IMG + File.separator + "copy.png";
        public static final String PASTE = Paths.ROOT_IMG + File.separator + "paste.png";
        public static final String SAVE = Paths.ROOT_IMG + File.separator + "save.png";
        public static final String ENF = Paths.ROOT_IMG + File.separator + "enfinity.png";
        public static final String IRC = Paths.ROOT_IMG + File.separator + "irc.png";
        public static final String REWARD = Paths.ROOT_IMG + File.separator + "irc.png";
        public static final String DELAY = Paths.ROOT_IMG + File.separator + "delay.png";
        public static final String OPTION = Paths.ROOT_IMG + File.separator + "option.png";
        public static final String DEV = Paths.ROOT_IMG + File.separator + "dev.png";
        public static final String VERSION = Paths.ROOT + File.separator + "version.dat";
        public static final String ITEMID = Paths.ROOT + File.separator + "ItemID.dat";
        public static final String NPCID = Paths.ROOT + File.separator + "NPCID.dat";
        public static final String SCRIPTS_NAME_SRC = "scripts";
        public static final String SCRIPTS_NAME_OUT = "Scripts";

        public static String getAccountsFile() {
            return Paths.getSettingsDirectory() + File.separator + "acts";
        }

        public static String getHomeDirectory() {
            final String env = System.getenv(GlobalConfiguration.NAME.toUpperCase() + "_HOME");
            if ((env == null) || env.isEmpty()) {
                return (GlobalConfiguration.getCurrentOperatingSystem() == OperatingSystem.WINDOWS ? FileSystemView.getFileSystemView().getDefaultDirectory().getAbsolutePath() : Paths.getUnixHome()) + File.separator + GlobalConfiguration.NAME;
            } else {
                return env;
            }
        }

        public static String getIconDirectory() {
            return Paths.getHomeDirectory() + File.separator + "icons";
        }

        public static String getItemIDDirectory() {
            return Paths.getCacheDirectory() + File.separator + "ItemID.dat";
        }

        public static String getLogsDirectory() {
            return Paths.getHomeDirectory() + File.separator + "Logs";
        }

        public static String getMenuCache() {
            return Paths.getSettingsDirectory() + File.separator + "Menu.txt";
        }

        public static String getPathCache() {
            return Paths.getSettingsDirectory() + File.separator + "path.txt";
        }

        public static String getUIDsFile() {
            return Paths.getSettingsDirectory() + File.separator + "uid.txt";
        }

        public static String getScreenshotsDirectory() {
            return Paths.getHomeDirectory() + File.separator + "Screenshots";
        }

        public static String getScriptsDirectory() {
            return Paths.getHomeDirectory() + File.separator + Paths.SCRIPTS_NAME_OUT;
        }

        public static String getScriptsPrecompiledDirectory() {
            return Paths.getScriptsDirectory() + File.separator + "Precompiled";
        }

        public static String getCacheDirectory() {
            return Paths.getHomeDirectory() + File.separator + "Cache";
        }

        public static String getVersionCache() {
            return Paths.getCacheDirectory() + File.separator + "info.dat";
        }

        public static String getModScriptCache() {
            return Paths.getCacheDirectory() + File.separator + "ms.dat";
        }

        public static String getClientCache() {
            return Paths.getCacheDirectory() + File.separator + "client.dat";
        }

        public static String getSettingsDirectory() {
            return Paths.getHomeDirectory() + File.separator + "Settings";
        }

        public static String getBreaksDirectory() {
            return Paths.getSettingsDirectory() + File.separator + "Breaks.txt";
        }

        public static String getUnixHome() {
            final String home = System.getProperty("user.home");
            return home == null ? "~" : home;
        }
        
        private static Map<String, File> cachableResources;

		public static Map<String, File> getCachableResources() {
			if (cachableResources == null) {
				cachableResources = new HashMap<String, File>(8);
				cachableResources.put(URLs.ITEMID, new File(getCacheDirectory(), "ItemID.dat"));
                                cachableResources.put(URLs.VERSION, new File(getCacheDirectory(), "version-latest.txt"));
			}
			return cachableResources;
		}
    }
    public static final String NAME = "Infinity";
    public static final String NAME_LOWERCASE = NAME.toLowerCase();
    public static final String SITE_NAME = "Lazygamerz";
    private static final OperatingSystem CURRENT_OS;
    public static boolean RUNNING_FROM_JAR = false;

    static {
        final URL resource = GlobalConfiguration.class.getClassLoader().getResource(Paths.Resources.VERSION);
        if (resource != null) {
            GlobalConfiguration.RUNNING_FROM_JAR = true;

        }
        /*
        String className = GlobalConfiguration.class.getName().replace('.', '/');
        String classJar = GlobalConfiguration.class.getResource(
        "/resources/version.dat").toString();
        if (classJar.startsWith("jar:")) {
        GlobalConfiguration.RUNNING_FROM_JAR = true;
        }

        System.out.println("runningfromjar " + GlobalConfiguration.RUNNING_FROM_JAR + " " + classJar);
         */

        final String os = System.getProperty("os.name");
        if (os.contains("Mac")) {
            CURRENT_OS = OperatingSystem.MAC;
        } else if (os.contains("Windows")) {
            CURRENT_OS = OperatingSystem.WINDOWS;
        } else if (os.contains("Linux")) {
            CURRENT_OS = OperatingSystem.LINUX;
        } else {
            CURRENT_OS = OperatingSystem.UNKNOWN;
        }

        final ArrayList<String> dirs = new ArrayList<String>();
        dirs.add(Paths.getHomeDirectory());
        dirs.add(Paths.getIconDirectory());
        dirs.add(Paths.getLogsDirectory());
        dirs.add(Paths.getCacheDirectory());
        dirs.add(Paths.getSettingsDirectory());
        if (GlobalConfiguration.RUNNING_FROM_JAR) {
            dirs.add(Paths.getScriptsDirectory());
            dirs.add(Paths.getScriptsPrecompiledDirectory());
        }

        for (final String name : dirs) {
            final File dir = new File(name);
            if (!dir.exists()) {
                dir.mkdirs();
            }
        }

        Properties logging = new Properties();
        String logFormatter = LogFormatter.class.getCanonicalName();
        String fileHandler = FileHandler.class.getCanonicalName();
        logging.setProperty("handlers", TextAreaLogHandler.class.getCanonicalName() + "," + fileHandler);
        logging.setProperty(".level", "INFO");
        logging.setProperty(SystemConsoleHandler.class.getCanonicalName() + ".formatter", logFormatter);
        logging.setProperty(fileHandler + ".formatter", logFormatter);
        logging.setProperty(TextAreaLogHandler.class.getCanonicalName() + ".formatter", logFormatter);
        logging.setProperty(fileHandler + ".pattern", Paths.getLogsDirectory() + File.separator + "%u.%g.log");
        logging.setProperty(fileHandler + ".count", "10");
        final ByteArrayOutputStream logout = new ByteArrayOutputStream();
        try {
            logging.store(logout, "");
            LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(logout.toByteArray()));
        } catch (final Exception ignored) {
        }

        if (GlobalConfiguration.RUNNING_FROM_JAR) {
            String path = resource.toString();
            try {
                path = URLDecoder.decode(path, "UTF-8");
            } catch (final UnsupportedEncodingException ignored) {
            }
            final String prefix = "jar:file:/";
            if (path.indexOf(prefix) == 0) {
                path = path.substring(prefix.length());
                path = path.substring(0, path.indexOf('!'));
                if (File.separatorChar != '/') {
                    path = path.replace('/', File.separatorChar);
                }
                try {
                    final File pathfile = new File(Paths.getPathCache());
                    if (pathfile.exists()) {
                        pathfile.delete();
                    }
                    pathfile.createNewFile();
                    Writer out = new BufferedWriter(new FileWriter(Paths.getPathCache()));
                    out.write(path);
                    out.close();
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static Image getImage(String resource, String path) {
        try {
            return Toolkit.getDefaultToolkit().getImage(GlobalConfiguration.RUNNING_FROM_JAR
                    ? GlobalConfiguration.class.getResource(resource) : new File(path).toURI().toURL());
        } catch (Exception ignored) {
        }
        return null;
    }

    public static OperatingSystem getCurrentOperatingSystem() {
        return GlobalConfiguration.CURRENT_OS;
    }

    public static String getHttpUserAgent() {
        String plat = "Windows", os = "Windows NT 5.2";
        if (GlobalConfiguration.getCurrentOperatingSystem() == GlobalConfiguration.OperatingSystem.MAC) {
            plat = "Macintosh";
            os = "Intel Mac OS X 10_6_4";
        } else if (GlobalConfiguration.getCurrentOperatingSystem() != GlobalConfiguration.OperatingSystem.WINDOWS) {
            plat = "X11";
            os = "Linux i686";
        }
        StringBuilder buf = new StringBuilder(125);
        buf.append("Mozilla/5.0 (").append(plat).append("; U; ").append(os);
        buf.append("; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7");
        return buf.toString();
    }

    public static URLConnection getURLConnection(final URL url, final String referer) throws IOException {
        final URLConnection con = url.openConnection();
        con.addRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        con.addRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
        con.addRequestProperty("Accept-Encoding", "gzip,deflate");
        con.addRequestProperty("Accept-Language", "en-us,en;q=0.5");
        con.addRequestProperty("Connection", "keep-alive");
        con.addRequestProperty("Host", url.getHost());
        con.addRequestProperty("Keep-Alive", "300");
        if (referer != null) {
            con.addRequestProperty("Referer", referer);
        }
        con.addRequestProperty("User-Agent", getHttpUserAgent());
        return con;
    }

    public static int getVersion() {
        try {
            InputStream is = RUNNING_FROM_JAR ? GlobalConfiguration.class.getClassLoader().getResourceAsStream(Paths.Resources.VERSION) : new FileInputStream(Paths.VERSION);

            int off = 0;
            byte[] b = new byte[2];
            while ((off += is.read(b, off, 2 - off)) != 2) {
            }

            return ((0xFF & b[0]) << 8) + (0xFF & b[1]);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }
}
